require 'zdc.doc'
require 'zsvc.que'
require 'zsvc.packet'
require 'zsvc.evhandle'
local monutil=require 'zsvc.monutil'
module(..., package.seeall)

local CBMap= {}
local CBMap_mt = {__metatable = {}, __index = CBMap}

function MakeInhMT(ch)
	ch=ch or {}
	for _i,_j in pairs(CBMap) do
		ch[_i]=_j
	end
	return ch
end


function CBMap:init_cbmag()
	self.cb_map={}
end

function CBMap:SetUserCB(ucb)
	self.usercb=ucb
end

function CBMap:QueryCB(sn)
	local old=self.cb_map[sn]
	if type(old) == 'table' then
		return old[1]
	else
		return old
	end
end
function CBMap:cbpcall(f,r1,r2)
	return pcall(f,self,r1,r2)
end
function CBMap:ResetCB()
	local cbpcall=self.cbpcall
	for k,v in pairs(self.cb_map) do
		if type(old) == 'table' then
			cbpcall(v[1],-1,'cancel')
		else
			cbpcall(v,-1,'cancel')
		end
	end
	self.cb_map={}
end

function CBMap:AddCBTimeout(sn,cb,ticks)
	local old=self.cb_map[sn]
	if old then self:cbpcall(old,-1,'replace by new') end
	if ticks then
		self.cb_map[sn]={cb,ticks}
	else
		self.cb_map[sn]=cb
	end
end

function CBMap:DelCB(sn,cb)
	local old=self:QueryCB(sn)
	self.cb_map[sn]=nil
	if old then self:cbpcall(old,-1,'cancel') end
end
function CBMap:DoCB(sn,ch,bd)
	local cb=self:QueryCB(sn)
	if cb then
		self.cb_map[sn]=nil
		local rp,r=self:cbpcall(cb,ch,bd)
		if not rp then print(rp,r) end
		return true
	end
end

function CBMap:DoTimeoutScan(ticknum)
	ticknum=ticknum or 1
	local to={}
	for k,v in pairs(self.cb_map) do
		if type(v)=='table' then
			v[2]=v[2]-ticknum
			if v[2]<=0 then
				table.insert(to,k)
			end
		end
	end
	local cbpcall=self.cbpcall
	for i=1,#to do
		local sn = to[i]
		local old=self:QueryCB(sn)
		self.cb_map[sn]=nil
		cbpcall(old,-1,'timeout')
	end
	return #to
end


